
package org.utn.edu.tsb.parser_xml.Interface;

import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import org.utn.edu.tsb.parser_xml.parser.NodeXML;
import org.utn.edu.tsb.parser_xml.parser.ParserXML;
import org.utn.edu.tsb.parser_xml.parser.XMLParseException;

/**
 *
 * @author Marcelo
 */
public class Main extends javax.swing.JFrame {
    
    String file = null;
    TreePath onEditPath = null;
    boolean loading = false;
    boolean changed = false;

    public Main() {

        this.setIconImage(new ImageIcon(getClass().getResource("/icon/xml.png")).getImage());
        initComponents();
        postSettings();
    }

    private void editNode() {
        onEditPath = jTree.getSelectionPath();
        NodeXML nodeObj = (NodeXML) (((DefaultMutableTreeNode) onEditPath.getLastPathComponent()).getUserObject());
        loadEdit(nodeObj);
        EditPanel.setVisible(true);
    }

    private void postSettings() {
        miGuardar.setEnabled(false);
        jTree.setCellRenderer(new CustomIconRenderer());
        EditPanel.setVisible(true);
        jTree.setLargeModel(true);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        treePopupMenu = new javax.swing.JPopupMenu();
        pmnuAdd = new javax.swing.JMenuItem();
        pmnuRemove = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JPopupMenu.Separator();
        pmnuEdit = new javax.swing.JMenuItem();
        EditPanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        txtName = new javax.swing.JTextField();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTable = new javax.swing.JTable();
        btnSaveNode = new javax.swing.JButton();
        btnRevert = new javax.swing.JButton();
        txtValue = new javax.swing.JTextField();
        btnNewAtt = new javax.swing.JButton();
        btnRemAtt = new javax.swing.JButton();
        jSeparator4 = new javax.swing.JSeparator();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTree = new javax.swing.JTree();
        btnSaveNode1 = new javax.swing.JButton();
        btnSaveNode2 = new javax.swing.JButton();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        miNuevoXml = new javax.swing.JMenuItem();
        miAbrir = new javax.swing.JMenuItem();
        miGuardar = new javax.swing.JMenuItem();
        jSeparator5 = new javax.swing.JPopupMenu.Separator();
        jMenu4 = new javax.swing.JMenu();
        miHistorial = new javax.swing.JMenuItem();
        jSeparator6 = new javax.swing.JPopupMenu.Separator();
        miSalir = new javax.swing.JMenuItem();
        jMenu3 = new javax.swing.JMenu();
        miAgregarNodo = new javax.swing.JMenuItem();
        miQuitarNodo = new javax.swing.JMenuItem();
        miEditar = new javax.swing.JMenuItem();
        jMenu2 = new javax.swing.JMenu();
        miAcercaDe = new javax.swing.JMenuItem();

        pmnuAdd.setMnemonic('a');
        pmnuAdd.setText("Agregar Nodo");
        pmnuAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pmnuAddActionPerformed(evt);
            }
        });
        treePopupMenu.add(pmnuAdd);

        pmnuRemove.setMnemonic('r');
        pmnuRemove.setText("Borrar Nodo");
        pmnuRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pmnuRemoveActionPerformed(evt);
            }
        });
        treePopupMenu.add(pmnuRemove);
        treePopupMenu.add(jSeparator3);

        pmnuEdit.setMnemonic('e');
        pmnuEdit.setText("Editar...");
        pmnuEdit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pmnuEditActionPerformed(evt);
            }
        });
        treePopupMenu.add(pmnuEdit);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Parser XML");
        setBounds(new java.awt.Rectangle(0, 0, 0, 0));
        setName("main"); // NOI18N

        jLabel1.setText("Nombre:");

        jLabel2.setText("Valor: ");

        txtName.setMinimumSize(new java.awt.Dimension(0, 28));

        jTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Title 1", "Title 2"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });
        jScrollPane2.setViewportView(jTable);

        btnSaveNode.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/edition/save.png"))); // NOI18N
        btnSaveNode.setMnemonic('s');
        btnSaveNode.setToolTipText("Guardar nodo");
        btnSaveNode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveNodeActionPerformed(evt);
            }
        });

        btnRevert.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/edition/close.png"))); // NOI18N
        btnRevert.setMnemonic('c');
        btnRevert.setToolTipText("Revertir cambios");
        btnRevert.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRevertActionPerformed(evt);
            }
        });

        txtValue.setMinimumSize(new java.awt.Dimension(0, 28));
        txtValue.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                txtValueKeyReleased(evt);
            }
        });

        btnNewAtt.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/edition/add.png"))); // NOI18N
        btnNewAtt.setToolTipText("New Attribute");
        btnNewAtt.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNewAttActionPerformed(evt);
            }
        });

        btnRemAtt.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/edition/delete.png"))); // NOI18N
        btnRemAtt.setToolTipText("Remove Attribute");
        btnRemAtt.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRemAttActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout EditPanelLayout = new javax.swing.GroupLayout(EditPanel);
        EditPanel.setLayout(EditPanelLayout);
        EditPanelLayout.setHorizontalGroup(
            EditPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(EditPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(EditPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(EditPanelLayout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, 229, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txtValue, javax.swing.GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, EditPanelLayout.createSequentialGroup()
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 605, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(EditPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(btnSaveNode, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(btnRevert, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(btnRemAtt, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(btnNewAtt, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addComponent(jSeparator4, javax.swing.GroupLayout.DEFAULT_SIZE, 638, Short.MAX_VALUE))
                .addContainerGap())
        );
        EditPanelLayout.setVerticalGroup(
            EditPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(EditPanelLayout.createSequentialGroup()
                .addContainerGap(24, Short.MAX_VALUE)
                .addGroup(EditPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2)
                    .addComponent(txtValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(EditPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(EditPanelLayout.createSequentialGroup()
                        .addComponent(btnNewAtt)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnRemAtt)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(btnSaveNode)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnRevert))
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator4, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        jTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode(new org.utn.edu.tsb.parser_xml.parser.NodeXML("", null))));
        jTree.setDoubleBuffered(true);
        jTree.setDragEnabled(true);
        jTree.setEnabled(false);
        jTree.setMaximumSize(new java.awt.Dimension(72, 600));
        jTree.setPreferredSize(new java.awt.Dimension(72, 600));
        jTree.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTreeMouseClicked(evt);
            }
        });
        jTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                jTreeValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(jTree);

        btnSaveNode1.setMnemonic('s');
        btnSaveNode1.setText("Salir");
        btnSaveNode1.setToolTipText("Salir");
        btnSaveNode1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveNode1ActionPerformed(evt);
            }
        });

        btnSaveNode2.setMnemonic('s');
        btnSaveNode2.setText("Guardar archivo");
        btnSaveNode2.setToolTipText("Guardar Archivo");
        btnSaveNode2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveNode2ActionPerformed(evt);
            }
        });

        jMenu1.setText("Archivo");

        miNuevoXml.setText("Nuevo archivo XML...");
        miNuevoXml.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miNuevoXmlActionPerformed(evt);
            }
        });
        jMenu1.add(miNuevoXml);

        miAbrir.setText("Abrir");
        miAbrir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miAbrirActionPerformed(evt);
            }
        });
        jMenu1.add(miAbrir);

        miGuardar.setText("Guardar");
        miGuardar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miGuardarActionPerformed(evt);
            }
        });
        jMenu1.add(miGuardar);
        jMenu1.add(jSeparator5);

        jMenu4.setText("Historial");

        miHistorial.setText("No ha seleccionado archivos anteriormente...");
        miHistorial.setEnabled(false);
        jMenu4.add(miHistorial);

        jMenu1.add(jMenu4);
        jMenu1.add(jSeparator6);

        miSalir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miSalirActionPerformed(evt);
            }
        });
        jMenu1.add(miSalir);

        jMenuBar1.add(jMenu1);

        jMenu3.setText("Editar");

        miAgregarNodo.setText("Agregar un nodo");
        miAgregarNodo.setEnabled(false);
        miAgregarNodo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miAgregarNodoActionPerformed(evt);
            }
        });
        jMenu3.add(miAgregarNodo);

        miQuitarNodo.setText("Quitar un nodo");
        miQuitarNodo.setEnabled(false);
        miQuitarNodo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miQuitarNodoActionPerformed(evt);
            }
        });
        jMenu3.add(miQuitarNodo);

        miEditar.setText("Editar");
        miEditar.setEnabled(false);
        miEditar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miEditarActionPerformed(evt);
            }
        });
        jMenu3.add(miEditar);

        jMenuBar1.add(jMenu3);

        jMenu2.setText("Ayuda");

        miAcercaDe.setText("Acerca de...");
        miAcercaDe.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miAcercaDeActionPerformed(evt);
            }
        });
        jMenu2.add(miAcercaDe);

        jMenuBar1.add(jMenu2);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 658, Short.MAX_VALUE)
            .addComponent(EditPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(440, Short.MAX_VALUE)
                .addComponent(btnSaveNode2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnSaveNode1)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 425, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(EditPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(btnSaveNode1)
                    .addComponent(btnSaveNode2))
                .addContainerGap(13, Short.MAX_VALUE))
        );

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-674)/2, (screenSize.height-750)/2, 674, 750);
    }// </editor-fold>//GEN-END:initComponents

    private void btnSaveNodeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveNodeActionPerformed
        saveEdition();
        jTree.repaint();
}//GEN-LAST:event_btnSaveNodeActionPerformed

    private void btnRevertActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRevertActionPerformed
        NodeXML nodeObj = (NodeXML) (((DefaultMutableTreeNode) onEditPath.getLastPathComponent()).getUserObject());
        loadEdit(nodeObj);
        checkContent();
    }//GEN-LAST:event_btnRevertActionPerformed

    private void jTreeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTreeMouseClicked
        if (jTree.getSelectionCount() == 1
                && !((DefaultMutableTreeNode) jTree.getSelectionPath().getLastPathComponent()).isRoot()) {
            if(((NodeXML)((DefaultMutableTreeNode)
                jTree.getSelectionPath().getLastPathComponent()).getUserObject()).getComment())
            {
                setButtonsAvailable(false);
                btnNewAtt.setEnabled(false);
                btnRemAtt.setEnabled(false);
                txtName.setEditable(false);
            }
            else
            {
                setButtonsAvailable(true);
                btnNewAtt.setEnabled(true);
                btnRemAtt.setEnabled(true);
                txtName.setEditable(true);
                checkContent();
                if (evt.getButton() == MouseEvent.BUTTON3) {
                    treePopupMenu.show(jTree, evt.getX(), evt.getY());
                }
            }                       
        } else {
            setButtonsAvailable(false);
        }
        checkContent();
    }//GEN-LAST:event_jTreeMouseClicked

    private void pmnuEditActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pmnuEditActionPerformed
        editNode();
    }//GEN-LAST:event_pmnuEditActionPerformed

    private void pmnuAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pmnuAddActionPerformed
        String nNodeName = JOptionPane.showInputDialog(this, "Nombre del nuevo nodo: ");
        if (nNodeName.compareToIgnoreCase("") == 0 || nNodeName == null) {
            return;
        }
        addChildToNode(nNodeName);
        saveEdition();
    }//GEN-LAST:event_pmnuAddActionPerformed

    private void pmnuRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pmnuRemoveActionPerformed
        removeChildNode();
        saveEdition();
    }//GEN-LAST:event_pmnuRemoveActionPerformed

    private void btnNewAttActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewAttActionPerformed
        ((DefaultTableModel) (jTable.getModel())).addRow(new String[2]);
}//GEN-LAST:event_btnNewAttActionPerformed

    private void btnRemAttActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemAttActionPerformed
        if (jTable.getSelectedRow() != -1) {
            ((DefaultTableModel) jTable.getModel()).removeRow(jTable.getSelectedRow());
        }
}//GEN-LAST:event_btnRemAttActionPerformed

    private void jTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_jTreeValueChanged
        onEditPath = jTree.getSelectionPath();
        if( jTree.getSelectionPath() != null &&
            ((NodeXML)((DefaultMutableTreeNode)
            jTree.getSelectionPath().getLastPathComponent()).getUserObject()).getComment())
        {
            setButtonsAvailable(false);
            btnNewAtt.setEnabled(false);
            btnRemAtt.setEnabled(false);
            txtName.setEditable(false);
        }
        else
        {
            setButtonsAvailable(true);
            btnNewAtt.setEnabled(true);
            btnRemAtt.setEnabled(true);
            txtName.setEditable(true);

        }
        try {
            NodeXML nodeObj = (NodeXML) (((DefaultMutableTreeNode) onEditPath.getLastPathComponent()).getUserObject());
            loadEdit(nodeObj);
        } catch (NullPointerException e) {
            System.out.println("No node");
            return;
        }

        checkContent();
    }//GEN-LAST:event_jTreeValueChanged

    private void txtValueKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtValueKeyReleased
        checkContent();
    }//GEN-LAST:event_txtValueKeyReleased

    private void miNuevoXmlActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miNuevoXmlActionPerformed
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setAcceptAllFileFilterUsed(false);
        fileChooser.addChoosableFileFilter(new XMLFileFilter());
        if (Persistence.getLastPath() != null) {
            fileChooser.setCurrentDirectory(new File(Persistence.getLastPath()));
        }
        int result = fileChooser.showSaveDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            String nXMLName = fileChooser.getSelectedFile().getName();
            if (!nXMLName.endsWith(".xml")) {
                nXMLName += ".xml";
                file = fileChooser.getSelectedFile().getAbsolutePath()+".xml";
            }else{
                file = fileChooser.getSelectedFile().getAbsolutePath();
            }

            setTitle("Parser XML - " + nXMLName);

            NodeXML newXML = new NodeXML(nXMLName, null);
            newXML.addNode(new NodeXML("Root", null));
            loadTreeNodes(newXML);
            jTree.setEnabled(true);
            miGuardar.setEnabled(true);
            Persistence.addFile(file);
            updateLastFileList();
            Persistence.savePath(fileChooser.getSelectedFile().getParent());
        }
    }//GEN-LAST:event_miNuevoXmlActionPerformed

    private void miAbrirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miAbrirActionPerformed
        loading = true;
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setAcceptAllFileFilterUsed(false);
        fileChooser.addChoosableFileFilter(new XMLFileFilter());
        if (Persistence.getLastPath() != null) {
            fileChooser.setCurrentDirectory(new File(Persistence.getLastPath()));
        }
        int result = fileChooser.showOpenDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {

            StringBuilder buffer = new StringBuilder();
            String line;
            FileReader fReader;
            BufferedReader bReader;
            try {
                  fReader = new FileReader(fileChooser.getSelectedFile().getAbsolutePath());
                  bReader = new BufferedReader(fReader);
                  while ((line = bReader.readLine()) != null){
                    buffer.append(line);
                  }
                  String content = buffer.toString();
                  Persistence.savePath(fileChooser.getSelectedFile().getParent());
                  bReader.close();
                  fReader.close();
                  content = content.trim().replaceAll("\n", "");
                  content = content.replaceAll("\t", "");
                  content = content.replaceAll("(\\s){2,}", "");
                  ParserXML parser = new ParserXML();
                  NodeXML nodo = parser.createXML(content);
                  this.jTree.removeAll();
                  file = fileChooser.getSelectedFile().getAbsolutePath();
                  setTitle("XML JParser - " + fileChooser.getSelectedFile().getName());
                  loadTreeNodes(nodo);
                  jTree.setEnabled(true);
                  miGuardar.setEnabled(true);
                  Persistence.addFile(fileChooser.getSelectedFile().getAbsolutePath());
                  updateLastFileList();
                }catch (FileNotFoundException e) {
                  Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, e);
                }catch (IOException e) {
                  Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, e);
                }catch (XMLParseException e){
                    JOptionPane.showMessageDialog(this, e.getMessage(), "Error - "+fileChooser.getSelectedFile().getName(), JOptionPane.ERROR_MESSAGE);
                }          
        }
        loading = false;
    }//GEN-LAST:event_miAbrirActionPerformed

    private void miGuardarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miGuardarActionPerformed
        SaveFile();
    }//GEN-LAST:event_miGuardarActionPerformed

    private void miSalirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miSalirActionPerformed
        this.dispose();
    }//GEN-LAST:event_miSalirActionPerformed

    private void miAcercaDeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miAcercaDeActionPerformed
        new Help().setVisible(true);
    }//GEN-LAST:event_miAcercaDeActionPerformed

    private void miQuitarNodoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miQuitarNodoActionPerformed
        removeChildNode();
        checkContent();
        saveEdition();
    }//GEN-LAST:event_miQuitarNodoActionPerformed

    private void miEditarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miEditarActionPerformed
        onEditPath = jTree.getSelectionPath();
        editNode();
    }//GEN-LAST:event_miEditarActionPerformed

    private void miAgregarNodoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miAgregarNodoActionPerformed
        String nNodeName = JOptionPane.showInputDialog(this, "Nombre del nuevo nodo: ");
        if (nNodeName.compareToIgnoreCase("") == 0 || nNodeName == null) {
            return;
        }
        addChildToNode(nNodeName);
        saveEdition();
    }//GEN-LAST:event_miAgregarNodoActionPerformed

    private void btnSaveNode2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveNode2ActionPerformed
        SaveFile();
    }//GEN-LAST:event_btnSaveNode2ActionPerformed

    private void btnSaveNode1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveNode1ActionPerformed
        this.dispose();
    }//GEN-LAST:event_btnSaveNode1ActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Main m = new Main();
                m.setExtendedState(MAXIMIZED_BOTH);
                m.setVisible(true);
            }
        });
    }

    private void addChildToNode(String nNodeName) {
        DefaultMutableTreeNode nNode = new DefaultMutableTreeNode(new NodeXML(nNodeName, null));
        MutableTreeNode node = (MutableTreeNode) jTree.getSelectionPath().getLastPathComponent();
        ((DefaultTreeModel) jTree.getModel()).insertNodeInto(nNode, node, node.getChildCount());
    }

    private void removeChildNode() {
        MutableTreeNode rNode = (MutableTreeNode) jTree.getSelectionPath().getLastPathComponent();
        ((DefaultTreeModel) jTree.getModel()).removeNodeFromParent(rNode);
    }

    private void setButtonsAvailable(Boolean enable) {
        pmnuAdd.setEnabled(enable);
        pmnuRemove.setEnabled(enable);
        pmnuEdit.setEnabled(enable);
        miAgregarNodo.setEnabled(enable);
        miQuitarNodo.setEnabled(enable);
        miEditar.setEnabled(enable);
    }


    private void loadTreeNodes(NodeXML node) {
        if (node.getName() == null
        || node.getName().compareTo(getTitle().split(" - ")[1]) == 0) {
            List<NodeXML> nodes = node.getNodes();
            NodeXML.restartIDs();
            NodeXML n = null;
            DefaultMutableTreeNode tNode = null;
            DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(
                    new NodeXML(getTitle().split(" - ")[1], null));
            DefaultTreeModel dtm = new DefaultTreeModel(rootNode);
            for(int i=0; i<nodes.size();i++){
                n = nodes.get(i);
                tNode = new DefaultMutableTreeNode(n);
                loadNodesContent(tNode, n);
                rootNode.add(tNode);                
            }
            jTree.setModel(dtm);
            setButtonsAvailable(false);
        }
    }

    private void loadNodesContent(DefaultMutableTreeNode treeNode, NodeXML node) {
        if (node.getNodes().size() > 0) {

            List<NodeXML> nodes = node.getNodes();
            NodeXML n;
            for(int i=0; i<nodes.size();i++){
                n = nodes.get(i);
                DefaultMutableTreeNode child = new DefaultMutableTreeNode(n);
                loadNodesContent(child, n);
                treeNode.add(child);
            }
        }

    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel EditPanel;
    private javax.swing.JButton btnNewAtt;
    private javax.swing.JButton btnRemAtt;
    private javax.swing.JButton btnRevert;
    private javax.swing.JButton btnSaveNode;
    private javax.swing.JButton btnSaveNode1;
    private javax.swing.JButton btnSaveNode2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenu jMenu3;
    private javax.swing.JMenu jMenu4;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JPopupMenu.Separator jSeparator3;
    private javax.swing.JSeparator jSeparator4;
    private javax.swing.JPopupMenu.Separator jSeparator5;
    private javax.swing.JPopupMenu.Separator jSeparator6;
    private javax.swing.JTable jTable;
    private javax.swing.JTree jTree;
    private javax.swing.JMenuItem miAbrir;
    private javax.swing.JMenuItem miAcercaDe;
    private javax.swing.JMenuItem miAgregarNodo;
    private javax.swing.JMenuItem miEditar;
    private javax.swing.JMenuItem miGuardar;
    private javax.swing.JMenuItem miHistorial;
    private javax.swing.JMenuItem miNuevoXml;
    private javax.swing.JMenuItem miQuitarNodo;
    private javax.swing.JMenuItem miSalir;
    private javax.swing.JMenuItem pmnuAdd;
    private javax.swing.JMenuItem pmnuEdit;
    private javax.swing.JMenuItem pmnuRemove;
    private javax.swing.JPopupMenu treePopupMenu;
    private javax.swing.JTextField txtName;
    private javax.swing.JTextField txtValue;
    // End of variables declaration//GEN-END:variables

    private void loadEdit(NodeXML node) {
        txtName.setText(node.getName());
        if (node.getValue() != null) {
            txtValue.setText(node.getValue());
        } else {
            txtValue.setText("");
        }
        String[] colNames = {"Attribute", "Value"};
        Object[][] props = new Object[node.getProperties().size()][2];
        if (node.getProperties() != null) {
            for (int i = 0; i < node.getProperties().size(); i++) {
                props[i][0] = node.getProperties().keySet().toArray()[i];
                props[i][1] = node.getProperties().values().toArray()[i];
            }
        }
        jTable.setModel(new DefaultTableModel(props, colNames));
    }

    private void checkContent() {
        DefaultMutableTreeNode dmtn = null;
        try {
            dmtn = ((DefaultMutableTreeNode) onEditPath.getLastPathComponent());
        } catch (Exception e) {
            return;
        }
        if (loading || dmtn.isRoot()) {
            return;
        }
        if (txtValue.getText().trim().compareToIgnoreCase("") != 0) {
            pmnuAdd.setEnabled(false);
            miAgregarNodo.setEnabled(false);
            txtValue.setEnabled(true);
        } else {
            if (dmtn.getChildCount() == 0) {
                pmnuAdd.setEnabled(true);
                miAgregarNodo.setEnabled(true);
                txtValue.setEnabled(true);
            } else {
                pmnuAdd.setEnabled(true);
                miAgregarNodo.setEnabled(true);
                txtValue.setEnabled(false);
            }
        }
    }

    private void saveEdition() {
        NodeXML toSave = null;
        try {
            toSave = ((NodeXML) ((DefaultMutableTreeNode) (onEditPath.getLastPathComponent())).getUserObject());
        } catch (NullPointerException e) {
            return;
        }
        toSave.setName(txtName.getText());
        toSave.setValue(txtValue.getText());
        if (txtValue.getText().compareToIgnoreCase("") == 0) {
            toSave.setValue(null);
        }
        TableModel model = jTable.getModel();
        toSave.getProperties().clear();
        for (int i = 0; i < model.getRowCount(); i++) {
            if (model.getValueAt(i, 0) != null && model.getValueAt(i, 1) != null) {
                toSave.addPropertie(model.getValueAt(i, 0).toString(), model.getValueAt(i, 1).toString());
            }
        }
        JOptionPane.showMessageDialog(this, "Se han guardado los datos del nodo", "Guardar nodo", JOptionPane.INFORMATION_MESSAGE);
        checkContent();
    }

    private void updateLastFileList(){

        String[] files = Persistence.getLastFiles();
        jMenu4.removeAll();
        if(files != null){
            for(int i=0; i < files.length ; i++){
                if(files[i]!= null && !files[i].toString().equals("")){
                    JMenuItem aux = new JMenuItem(files[i]);
                    aux.addActionListener(new ActionListener(){

                            @Override
                            public void actionPerformed(ActionEvent e) {
                                StringBuilder buffer = new StringBuilder();
                                String line;
                                FileReader fReader;
                                BufferedReader bReader;
                                try {
                                    String filePath = ((JMenuItem)e.getSource()).getText();
                                    fReader = new FileReader(filePath);
                                    bReader = new BufferedReader(fReader);
                                    while ((line = bReader.readLine()) != null){
                                        buffer.append(line);
                                    }
                                    String content = buffer.toString();
                                    bReader.close();
                                    fReader.close();
                                    content = content.trim().replaceAll("\n", "");
                                    content = content.replaceAll("\t", "");
                                    content = content.replaceAll("(\\s){2,}", "");
                                    ParserXML parser = new ParserXML();
                                    NodeXML nodo = parser.createXML(content);
                                    jTree.removeAll();
                                    
                                    setTitle("Parser XML - " + filePath);
                                    loadTreeNodes(nodo);
                                    jTree.setEnabled(true);
                                    miGuardar.setEnabled(true);
                                }catch (FileNotFoundException ex) {
                                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, e);
                                }catch (IOException ex) {
                                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, e);
                                } catch (XMLParseException ex) {
                                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                                }
                            }
                        });
                        jMenu4.add(aux);
                }
            }
        }
    }

    private void SaveFile(){
                try {
            BufferedWriter bwriter;
            bwriter = new BufferedWriter(new FileWriter(file));
             String xml = (new ParserXML().getString(
                    (DefaultMutableTreeNode) jTree.getPathForRow(0).getLastPathComponent()));
             bwriter.write(xml);
             bwriter.close();
            JOptionPane.showMessageDialog(this,
                                          this.getTitle().split(" - ")[1] + " succesfully saved.",
                                          "File Save",
                                          JOptionPane.INFORMATION_MESSAGE);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this,
                    this.getTitle().split(" - ")[1] + " couldn't be saved.",
                    "File Save",
                    JOptionPane.WARNING_MESSAGE);
        }
    }
}